<template>
  <div
    class="pdf-preview"
    v-loading="loading"
    :element-loading-text="loadingText"
    @mousemove="handleMouseMove"
  >
    <div class="pdf-wrap" id="pdf-wrap">
      <VuePdfEmbed
        ref="vuePdfRef"
        :source="state.source"
        :style="scale"
        :rotation="rotation"
        :page="state.pageNum"
        class="vue-pdf-embed"
        @loading-failed="handleFailed"
        @loaded="handleDocumentLoad"
        @rendered="handleDocumentRender"
        @rendering-failed="handleDocumentRenderError"
        @progress="handleProgress"
      />
    </div>
    <div class="page-tool" :class="{ show: isToolVisible }">
      <div class="page-tool-item" @click="lastPage">
        <el-tooltip
          class="box-item"
          effect="dark"
          content="上一页"
          placement="top"
          ><el-icon><Back /></el-icon
        ></el-tooltip>
      </div>
      <div class="page-tool-item" @click="nextPage">
        <el-tooltip
          class="box-item"
          effect="dark"
          content="下一页"
          placement="top"
          ><el-icon><Right /></el-icon
        ></el-tooltip>
      </div>
      <div class="page-tool-item">
        <el-input
          v-model="jumpPage"
          style="width: 30px"
          size="small"
          @blur="toPage(jumpPage)"
          @keyup.enter="toPage(jumpPage)"
        ></el-input>
        <el-text class="mx-1" style="color: #999"
          >&nbsp;/{{ state.numPages }}</el-text
        >
      </div>
      <div class="page-tool-item" @click="pageZoomOut">
        <el-tooltip
          class="box-item"
          effect="dark"
          content="放大"
          placement="top"
          ><el-icon><ZoomIn /></el-icon
        ></el-tooltip>
      </div>
      <div class="page-tool-item" @click="pageZoomIn">
        <el-tooltip
          class="box-item"
          effect="dark"
          content="缩小"
          placement="top"
          ><el-icon><ZoomOut /></el-icon
        ></el-tooltip>
      </div>
      <div class="page-tool-item" @click="pageRotation">
        <el-tooltip
          class="box-item"
          effect="dark"
          content="旋转"
          placement="top"
          ><el-icon><RefreshRight /></el-icon
        ></el-tooltip>
      </div>
      <div class="page-tool-item" @click="restore">
        <el-tooltip
          class="box-item"
          effect="dark"
          content="还原"
          placement="top"
          ><el-icon><Refresh /></el-icon
        ></el-tooltip>
      </div>
      <div class="page-tool-item" @click="print" v-if="props.showPrint">
        <el-tooltip
          class="box-item"
          effect="dark"
          content="打印"
          placement="top"
          ><el-icon><Printer /></el-icon
        ></el-tooltip>
      </div>
      <div class="page-tool-item" @click="download" v-if="props.showDownload">
        <el-tooltip
          class="box-item"
          effect="dark"
          content="下载"
          placement="top"
          ><el-icon><Download /></el-icon
        ></el-tooltip>
      </div>
    </div>
  </div>
</template>
<script setup>
import VuePdfEmbed from "vue-pdf-embed";
import { ElMessage } from "element-plus";
import {
  ref,
  reactive,
  computed,
  watch,
  onMounted,
  onUnmounted,
  nextTick,
} from "vue";

const jumpPage = ref(1);
const props = defineProps({
  source: {
    type: String,
    required: true,
  },
  showPrint: {
    type: Boolean,
    default: true,
  },
  showDownload: {
    type: Boolean,
    default: true,
  },
});
const state = reactive({
  source: props.source,
  pageNum: 1,
  scale: 1,
  numPages: 0,
});
const vuePdfRef = ref(null);
const rotation = ref(0);
const loading = ref(true);
const loadingText = ref("加载中...");
const scale = computed(() => `transform:scale(${state.scale})`);
const scrollPosition = ref(0);
const isToolVisible = ref(false);
function handleDocumentLoad(pdfInfo) {
  state.numPages = pdfInfo._pdfInfo.numPages;
}

function handleDocumentRender() {
  loading.value = false;
  isToolVisible.value = true;
  // 恢复滚动条位置
  nextTick(() => {
    const el = document.getElementById("pdf-wrap");
    if (el) {
      el.scrollTop = scrollPosition.value;
    }
  });
}

function handleDocumentRenderError() {
  loading.value = false;
  ElMessage({ message: "文档渲染失败", type: "error" });
}

function handleFailed() {
  loading.value = false;
  ElMessage({ message: "文档加载失败", type: "error" });
}

function handleProgress(obj) {
  const progress = Math.floor((obj.loaded / obj.total) * 100);
  loadingText.value = "加载" + progress + "%";
}
function lastPage() {
  if (state.pageNum > 1) {
    state.pageNum -= 1;
  }
  jumpPage.value = state.pageNum;
  // 保存当前滚动条位置
  const el = document.getElementById("pdf-wrap");
  if (el) {
    scrollPosition.value = el.scrollTop;
  }
}
function nextPage() {
  if (state.pageNum < state.numPages) {
    state.pageNum += 1;
  }
  jumpPage.value = state.pageNum;
  // 保存当前滚动条位置
  const el = document.getElementById("pdf-wrap");
  if (el) {
    scrollPosition.value = el.scrollTop;
  }
}
function toPage(val) {
  if (isNaN(Number(val)) || !val || Number(val) < 1) {
    jumpPage.value = 1;
    state.pageNum = 1;
  } else if (Number(val) > state.numPages) {
    jumpPage.value = state.numPages;
    state.pageNum = state.numPages;
  } else {
    state.pageNum = Number(val);
  }
  // 保存当前滚动条位置
  const el = document.getElementById("pdf-wrap");
  if (el) {
    scrollPosition.value = el.scrollTop;
  }
}

function pageZoomOut() {
  if (state.scale < 2) {
    state.scale += 0.1;
  }
}
function pageZoomIn() {
  if (state.scale > 1) {
    state.scale -= 0.1;
  }
}
function pageRotation() {
  rotation.value += 90;
}
function download() {
  vuePdfRef.value?.download("1.pdf");
}

function restore() {
  state.scale = 1;
  rotation.value = 0;
}

function print() {
  vuePdfRef.value?.print(300, "1.pdf", false);
}
function handleMouseMove(event) {
  const toolRect = document.querySelector(".page-tool").getBoundingClientRect();
  const isMouseOverTool =
    event.clientX >= toolRect.left &&
    event.clientX <= toolRect.right &&
    event.clientY >= toolRect.top &&
    event.clientY <= toolRect.bottom;

  if (isMouseOverTool) {
    isToolVisible.value = true;
  } else {
    isToolVisible.value = false;
  }
}
</script>
<style lang="scss" scoped>
.pdf-preview {
  width: 100%;
  height: 100%;
  display: flex;
  padding: 10px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: relative;
  background-color: gray;
}
.pdf-wrap {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
// .vue-pdf-embed {
//   width: 100%;
//   height: 100%;
//   display: flex;
//   align-items: center;
//   justify-content: center;
// }
// .pdf-preview {
//   position: relative;
//   height: 100vh;
//   padding: 20px 0;
//   box-sizing: border-box;
//   background-color: gray;
// }

// .pdf-preview .pdf-wrap {
//   height: 100%;
//   overflow-y: auto;
// }

.vue-pdf-embed {
  height: 100%;
  text-align: center;
  width: 1000px;
  margin: 0 auto;
  box-sizing: border-box;
}
.page-tool {
  position: absolute;
  bottom: 25px;
  padding-left: 15px;
  padding-right: 15px;
  display: flex;
  flex: auto;
  align-items: center;
  margin: 0 auto;
  background: rgb(66, 66, 66);
  color: white;
  border-radius: 19px;
  z-index: 100;
  cursor: pointer;
  text-align: center;
  margin-left: 30%;
  transform: translateX(-50%);
  opacity: 1;
}

.page-tool.show {
  // display: flex;
  transition: opacity 0.3s ease;
  opacity: 1;
}
.page-tool-item {
  padding: 8px 15px;
  padding-left: 10px;
  cursor: pointer;
}
/* 自定义加载遮罩样式 */
:deep(.el-loading-mask) {
  display: flex;
  align-items: center;
  justify-content: center;
  /* background-color: rgba(0, 0, 0, 0.8); */
  top: 300px;
  /* height: 100vh; */
}
:deep(.el-input__wrapper) {
  padding: 0 2px 0 2px;
}
:deep(.el-input__inner) {
  text-align: right;
}
</style>
